﻿#ifndef THREAD_POOL_H
#define THREAD_POOL_H
#include <memory>
#include <vector>

#include "ReflectX_global.h"
#include "workcondition.h"

//线程池使用事项
/*
1.已被执行完毕的任务不能复用，就算扔进线程池里也不会再次执行
2.有依赖的任务不可以扔到不同的线程池内，比如J2依赖J1，J2和J1分别扔到不同的线程池内，可能会造成死锁
3.如果J2依赖J1，先扔进去的是J2，那么线程池不会做任何事，直到J1来到，才会按顺序处理J1 J2
*/

class ThreadJob;
typedef std::shared_ptr<ThreadJob> ThreadJobPtr;
typedef std::vector<ThreadJobPtr> ThreadJobList;

class ThreadPool;

class REFLECTX_EXPORT ThreadJob
{
public:
	ThreadJob(const ThreadJobList& relys);//这里只允许在创建任务的时候就设置好依赖项，一来是为了防止运行过程中改变依赖项而造成更多麻烦，二来是为了避免环路现象产生

	bool isFinished() const;

	static ThreadJobPtr CreateJob(std::function<void()> fun, const ThreadJobList& relys = {});

protected:
	virtual void Run() = 0;

private:
	ThreadJobList relys;
	bool m_finished;
	friend class ThreadPool;
};

class REFLECTX_EXPORT ThreadPool
{
public:
	enum IncrementPolicy
	{
		Fixed,
		IncreseOnNeed,
	};


	ThreadPool(int initThreadCount,int MaxThreadCount,IncrementPolicy policy = IncreseOnNeed);
	~ThreadPool();

	//向线程池内提交任务
	void PostJob(ThreadJobPtr job);
	void PostJob(const ThreadJobList& jobs);

	void shut();//清空线程池内的所有任务，禁止再投入任务
	void join();//等待线程池内的所有任务
	void stop();//清空线程池内的所有任务，禁止再投入任务并等待线程池内的所有任务

private:
	struct Private;
	std::unique_ptr<Private> _P;
};


#endif // !THREAD_POOL_H
